package gui;

import group.UserGroup;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Iterator;
import java.util.ListIterator;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ScrollPaneLayout;
import javax.swing.SwingConstants;
import javax.swing.border.EtchedBorder;

import role.Role;
import role.RoleFactory;
import seminar.Seminar;
import student.Student;

public class EditGroupsPane extends JLayeredPane
{
	// TODO Fehler ausmerzen
	private JTextField selGroupNameTF;
	private JTextField groupNameTF;
	private JTextField sizeTF;
	private JTextField ownerDataTF;
	private JLabel curGroupSizeLBL;
	private JList groupsList, roleList;
	private JButton changeGroupNameBT, delGroupBT, addGroupBT,
			curGroupLessMembersBT, curGroupMoreMembersBT, moreMembersBT,
			lessMembersBT, freeRoleBT, changeBT;
	private JComboBox roleSelCB;
	private int lastSelectedGroup;
	

	public EditGroupsPane()
	{

		setLayout(new BorderLayout(0, 0));
		JScrollPane groupListScrollPane = new JScrollPane();
		JPanel groupListPanel = new JPanel();
		add(groupListScrollPane, BorderLayout.WEST);
		groupListScrollPane.setViewportView(groupListPanel);
		groupListPanel.setLayout(new BorderLayout(0, 0));

		this.groupsList = new JList();
		this.groupsList.addMouseListener(selectedElement());

		groupListPanel.add(groupsList);

		Component horizontalStrut_6 = Box.createHorizontalStrut(100);
		groupListPanel.add(horizontalStrut_6, BorderLayout.NORTH);

		JPanel groupSetPanel = new JPanel();
		add(groupSetPanel, BorderLayout.CENTER);
		groupSetPanel.setLayout(new BorderLayout(0, 0));
		

		JPanel groupNameDelPanel = new JPanel();
		groupNameDelPanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED,
				null, null));
		groupSetPanel.add(groupNameDelPanel, BorderLayout.NORTH);
		groupNameDelPanel.setLayout(new BoxLayout(groupNameDelPanel,
				BoxLayout.X_AXIS));

		Component horizontalStrut_5 = Box.createHorizontalStrut(20);
		groupNameDelPanel.add(horizontalStrut_5);

		JLabel selGroupNameLBL = new JLabel("Name:");
		groupNameDelPanel.add(selGroupNameLBL);

		Component horizontalStrut_1 = Box.createHorizontalStrut(20);
		groupNameDelPanel.add(horizontalStrut_1);

		selGroupNameTF = new JTextField();
		groupNameDelPanel.add(selGroupNameTF);
		selGroupNameTF.setColumns(10);

		Component horizontalStrut_2 = Box.createHorizontalStrut(20);
		groupNameDelPanel.add(horizontalStrut_2);

		changeGroupNameBT = new JButton("Ändern");
		changeGroupNameBT.setFont(new Font("Dialog", Font.BOLD, 12));
		changeGroupNameBT.addActionListener(buttonPressed());
		groupNameDelPanel.add(changeGroupNameBT);

		Component horizontalStrut_3 = Box.createHorizontalStrut(20);
		groupNameDelPanel.add(horizontalStrut_3);

		delGroupBT = new JButton("Löschen");
		delGroupBT.setFont(new Font("Dialog", Font.BOLD, 12));
		delGroupBT.addActionListener(buttonPressed());
		groupNameDelPanel.add(delGroupBT);

		Component horizontalStrut_4 = Box.createHorizontalStrut(20);
		groupNameDelPanel.add(horizontalStrut_4);

		JPanel groupRolesPanel = new JPanel();
		groupSetPanel.add(groupRolesPanel, BorderLayout.CENTER);
		groupRolesPanel.setLayout(new BorderLayout(0, 0));

		JPanel groupRolesSelPanel = new JPanel();
		JScrollPane groupRolesSelScrollPane = new JScrollPane();
		groupRolesSelScrollPane.setPreferredSize(new Dimension(250,250));
		
		groupRolesSelScrollPane.setViewportView(groupRolesSelPanel);
		
		groupRolesPanel.add(groupRolesSelScrollPane, BorderLayout.WEST);

		groupRolesSelPanel.setLayout(new BorderLayout(0, 0));
		roleList = new JList();
		
		roleList.addMouseListener(selectedElement());
		groupRolesSelPanel.add(roleList);

		Component horizontalStrut_7 = Box.createHorizontalStrut(179);
		groupRolesSelPanel.add(horizontalStrut_7, BorderLayout.NORTH);

		JPanel groupRoleSetPanel = new JPanel();
		groupRolesPanel.add(groupRoleSetPanel, BorderLayout.EAST);
		groupRoleSetPanel.setLayout(new BorderLayout(0, 0));

		Box verticalBox = Box.createVerticalBox();
		verticalBox
				.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null, null));
		groupRoleSetPanel.add(verticalBox, BorderLayout.NORTH);

		JLabel roleChoiceLBL = new JLabel("Rollenauswahl:");
		verticalBox.add(roleChoiceLBL);
		roleChoiceLBL.setAlignmentX(Component.CENTER_ALIGNMENT);
		roleChoiceLBL.setHorizontalAlignment(SwingConstants.CENTER);

		JPanel panel = new JPanel();
		verticalBox.add(panel);

		Box horizontalBox = Box.createHorizontalBox();
		panel.add(horizontalBox);

		roleSelCB = new JComboBox();
		roleSelCB.setAlignmentX(Component.RIGHT_ALIGNMENT);
		roleSelCB.addActionListener(factRoleSelected());
		loadFactoryRoles();

		horizontalBox.add(roleSelCB);

		Component horizontalStrut = Box.createHorizontalStrut(20);
		horizontalBox.add(horizontalStrut);

		changeBT = new JButton("Ändern");
		changeBT.addActionListener(buttonPressed());
		horizontalBox.add(changeBT);

		Box verticalBox_1 = Box.createVerticalBox();
		verticalBox_1.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null,
				null));
		groupRoleSetPanel.add(verticalBox_1, BorderLayout.CENTER);

		Component verticalGlue = Box.createVerticalGlue();
		verticalBox_1.add(verticalGlue);

		JLabel roleOwnerLBL = new JLabel("Rolleninhaber:");
		roleOwnerLBL.setAlignmentX(Component.CENTER_ALIGNMENT);
		roleOwnerLBL.setHorizontalAlignment(SwingConstants.CENTER);
		verticalBox_1.add(roleOwnerLBL);

		JPanel panel_1 = new JPanel();
		verticalBox_1.add(panel_1);

		Box verticalBox_2 = Box.createVerticalBox();
		panel_1.add(verticalBox_2);

		ownerDataTF = new JTextField();
		verticalBox_2.add(ownerDataTF);
		ownerDataTF.setColumns(10);

		freeRoleBT = new JButton("Leeren");
		freeRoleBT.addActionListener(buttonPressed());
		verticalBox_2.add(freeRoleBT);

		Box verticalBox_3 = Box.createVerticalBox();
		verticalBox_3.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null,
				null));
		groupRoleSetPanel.add(verticalBox_3, BorderLayout.SOUTH);

		JLabel groupSizeLBL = new JLabel("Gruppengröße");
		groupSizeLBL.setAlignmentX(Component.CENTER_ALIGNMENT);
		groupSizeLBL.setHorizontalAlignment(SwingConstants.CENTER);
		verticalBox_3.add(groupSizeLBL);

		JPanel panel_2 = new JPanel();
		verticalBox_3.add(panel_2);

		Box horizontalBox_1 = Box.createHorizontalBox();
		panel_2.add(horizontalBox_1);

		curGroupLessMembersBT = new JButton("-");
		curGroupLessMembersBT.addActionListener(buttonPressed());
		horizontalBox_1.add(curGroupLessMembersBT);

		Component horizontalStrut_8 = Box.createHorizontalStrut(20);
		horizontalBox_1.add(horizontalStrut_8);

		curGroupSizeLBL = new JLabel();
		curGroupSizeLBL.setHorizontalAlignment(SwingConstants.CENTER);
		curGroupSizeLBL.setText("3");
		horizontalBox_1.add(curGroupSizeLBL);
		//curGroupSizeLBL.setColumns(3);

		curGroupMoreMembersBT = new JButton("+");
		curGroupMoreMembersBT.addActionListener(buttonPressed());

		Component horizontalStrut_9 = Box.createHorizontalStrut(20);
		horizontalBox_1.add(horizontalStrut_9);
		horizontalBox_1.add(curGroupMoreMembersBT);

		JPanel groupCreatePanel = new JPanel();
		groupSetPanel.add(groupCreatePanel, BorderLayout.SOUTH);
		groupCreatePanel.setBorder(new EtchedBorder(EtchedBorder.LOWERED, null,
				null));
		groupCreatePanel.setLayout(new BorderLayout(0, 0));

		JPanel labelPanel = new JPanel();
		groupCreatePanel.add(labelPanel, BorderLayout.NORTH);

		JLabel addGroupLBL = new JLabel("Gruppenerstellung:");
		addGroupLBL.setHorizontalAlignment(SwingConstants.LEFT);
		labelPanel.add(addGroupLBL);

		JPanel newGroupDataPanel = new JPanel();
		groupCreatePanel.add(newGroupDataPanel, BorderLayout.SOUTH);
		newGroupDataPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

		groupNameTF = new JTextField();
		groupNameTF.setText("Name");
		newGroupDataPanel.add(groupNameTF);
		groupNameTF.setColumns(10);

		lessMembersBT = new JButton("-");
		lessMembersBT.setFont(new Font("Dialog", Font.BOLD, 12));
		lessMembersBT.addActionListener(buttonPressed());

		newGroupDataPanel.add(lessMembersBT);

		sizeTF = new JTextField();
		sizeTF.setHorizontalAlignment(SwingConstants.CENTER);
		sizeTF.setText("3");
		newGroupDataPanel.add(sizeTF);
		sizeTF.setColumns(3);

		moreMembersBT = new JButton("+");
		moreMembersBT.setFont(new Font("Dialog", Font.BOLD, 12));
		moreMembersBT.addActionListener(buttonPressed());
		newGroupDataPanel.add(moreMembersBT);

		addGroupBT = new JButton("Hinzufügen");
		addGroupBT.setFont(new Font("Dialog", Font.BOLD, 12));
		addGroupBT.addActionListener(buttonPressed());
		newGroupDataPanel.add(addGroupBT);
		this.enableGroupContent(false);
		this.enableRoleContent(false);

		loadSeminarData();

	}

	private void loadSeminarData()
	{

		DefaultListModel listmodel = new DefaultListModel();
		Iterator<UserGroup> iter = Seminar.getUsergoups().iterator();
		if (iter.hasNext())
			while (iter.hasNext())
			{

				listmodel.addElement(iter.next().getName());

			}
		this.groupsList.setModel(listmodel);
		
		groupsList.setSelectedIndex(this.lastSelectedGroup);
		
		if (!Seminar.getUsergoups().isEmpty())
			selGroupNameTF.setText(groupsList.getSelectedValue().toString());
		else
			selGroupNameTF.setText("");
	}

	private void loadFactoryRoles()
	{

		Iterator<Role> factRoles = RoleFactory.getRoles().iterator();
		DefaultComboBoxModel combomodel = new DefaultComboBoxModel();
		while (factRoles.hasNext())
		{

			combomodel.addElement(factRoles.next().getName());

		}
		roleSelCB.setModel(combomodel);
	}

	private void loadGroupRoles()
	{

		if (!Seminar.getUsergoups().isEmpty())
		{
			Iterator<Role> groupRoles = Seminar
					.getUserGroupByName(
							groupsList.getSelectedValue().toString())
					.getRoles().iterator();
			DefaultListModel groupRolesListModel = new DefaultListModel();
			String listEntry;
			Role tmprole;
			while (groupRoles.hasNext())
			{
				tmprole = groupRoles.next();
				listEntry = tmprole.getName();
				if (tmprole.getStudent() != null)
					listEntry += " - " + tmprole.getStudent().getFirstName()
							+ " " + tmprole.getStudent().getLastName();
				groupRolesListModel.addElement(listEntry);

			}
			roleList.setModel(groupRolesListModel);
		} else
		{
			roleList.setModel(new DefaultListModel());
		}

	}

	private MouseListener selectedElement()
	{
		return new MouseAdapter() {

			@Override
			public void mousePressed(MouseEvent me)
			{

				if (me.getSource().equals(groupsList))
				{	
					if(groupsList.getModel().getSize() != 0)
					{
						lastSelectedGroup = groupsList.getSelectedIndex();
						
						loadGroupRoles();
						selGroupNameTF.setText(groupsList.getSelectedValue()
								.toString());
						
						curGroupSizeLBL.setText(new Integer(Seminar
							.getUserGroupByName(
									groupsList.getSelectedValue().toString())
							.getMaxSize()).toString());
						enableGroupContent(true);
					}
					
				}

				if (me.getSource().equals(roleList))
				{
					Student tmpst;
					
					if (groupsList.getSelectedValue() == null)
					{
						GUI.statusausgabe("Bitte eine Gruppe wählen");
					} else
					{
						if ((tmpst = Seminar
								.getUserGroupByName(
										groupsList.getSelectedValue()
												.toString()).getRoles()
								.get(roleList.getSelectedIndex()).getStudent()) != null)
						{
							ownerDataTF.setText(tmpst.getFirstName() + " "
									+ tmpst.getLastName());
							ownerDataTF.setName(tmpst.getLastName());
							roleSelCB.setName(new Integer(roleList
									.getSelectedIndex()).toString());
							
						} else
						{
							ownerDataTF.setText("");
							roleSelCB.setName(new Integer(roleList
									.getSelectedIndex()).toString());
							GUI.statusausgabe("Ausgewählter Rolle ist kein Student zugeordnet");
						}
						enableRoleContent(true);
						
					}

				}

			}

		};
	}

	private ActionListener buttonPressed()
	{

		return new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent ae)
			{
				if (ae.getSource().equals(changeGroupNameBT))
				{

					Iterator<UserGroup> iter = Seminar.getUsergoups()
							.iterator();
					while (iter.hasNext())
					{
						UserGroup tmpug = iter.next();
						if (tmpug.getName().equals(
								groupsList.getSelectedValue().toString()))
						{
							Seminar.getUsergoups().remove(tmpug);
							tmpug.setName(selGroupNameTF.getText());
							Seminar.getUsergoups().add(tmpug);
							GUI.statusausgabe("Gruppe wurde umbenannt");
							loadSeminarData();
							break;
						}
					}
				}

				if (ae.getSource().equals(delGroupBT))
				{

					Iterator<UserGroup> iter = Seminar.getUsergoups()
							.iterator();
					while (iter.hasNext())
					{
						UserGroup tmpug = iter.next();
						if (tmpug.getName().equals(
								groupsList.getSelectedValue().toString()))
						{
							Seminar.getUsergoups().remove(tmpug);

							Iterator<Role> roleiter = tmpug.getRoles()
									.iterator();
							while (roleiter.hasNext())
							{

								Seminar.getSystemgroup().addStudent(
										roleiter.next().getStudent());
							}

							if (!Seminar.getUsergoups().isEmpty())
								groupsList.setSelectedIndex(0);

							GUI.statusausgabe("Gruppe "
									+ selGroupNameTF.getText()
									+ " wurde gelöscht");
							selGroupNameTF.setText("");
							lastSelectedGroup = 0;
							loadSeminarData();
							loadGroupRoles();
							GUI.updateAll();
							break;
						}
					}
					if(groupsList.getModel().getSize() == 0) enableGroupContent(false);

				}

				// Listener: Gruppe hinzufügen
				if (ae.getSource().equals(addGroupBT))
				{

					if (groupNameTF.getText().equals("Name")
							|| groupNameTF.getText().equals(""))
					{
						GUI.statusausgabe("Bitte einen korrekten Namen angeben!");
					} else
					{
						UserGroup ug = new UserGroup(new Integer(
								sizeTF.getText()), groupNameTF.getText());
						Seminar.getUsergoups().add(ug);
						GUI.statusausgabe("Gruppe wurde hinzugefügt");
						
						
						loadSeminarData();
						groupsList.setSelectedIndex(groupsList.getLastVisibleIndex());
						loadGroupRoles();
						groupNameTF.setText("");
						// GUI.updateAll();
					}

				}

				if (ae.getSource().equals(curGroupLessMembersBT))
				{

					if (Seminar.getUserGroupByName(
							groupsList.getSelectedValue().toString())
							.hasSpace())
					{
						Seminar.getUserGroupByName(
								groupsList.getSelectedValue().toString())
								.setMaxSize(
										Seminar.getUserGroupByName(
												groupsList.getSelectedValue()
														.toString())
												.getMaxSize() - 1);
						curGroupSizeLBL.setText(new Integer(Seminar
								.getUserGroupByName(
										groupsList.getSelectedValue()
												.toString()).getMaxSize())
								.toString());
						ListIterator<Role> roleIter = Seminar
								.getUserGroupByName(
										groupsList.getSelectedValue()
												.toString()).getRoles()
								.listIterator();
						Role tmprole;
						while (roleIter.hasNext())
						{
							if ((tmprole = roleIter.next()).getStudent() == null)
							{

								Seminar.getUserGroupByName(
										groupsList.getSelectedValue()
												.toString()).getRoles()
										.remove(tmprole);
								break;
							}
						}
						loadSeminarData();
						loadGroupRoles();
					} else
					{
						GUI.statusausgabe("gewünschte Größe kleiner als Teilnehmerzahl!");
					}
					
					if(roleList.getModel().getSize() == 0) enableRoleContent(false);
				}

				if (ae.getSource().equals(curGroupMoreMembersBT))
				{
					Seminar.getUserGroupByName(
							groupsList.getSelectedValue().toString())
							.setMaxSize(
									Seminar.getUserGroupByName(
											groupsList.getSelectedValue()
													.toString()).getMaxSize() + 1);
					Seminar.getUserGroupByName(
							groupsList.getSelectedValue().toString())
							.getRoles().add(RoleFactory.getStandardRole());
					curGroupSizeLBL.setText(new Integer(Seminar
							.getUserGroupByName(
									groupsList.getSelectedValue().toString())
							.getMaxSize()).toString());
					loadSeminarData();
					loadGroupRoles();
				}

				if (ae.getSource().equals(lessMembersBT))
				{
					Integer tmp = new Integer(sizeTF.getText());
					tmp -= 1;
					sizeTF.setText(tmp.toString());
				}

				if (ae.getSource().equals(moreMembersBT))
				{
					Integer tmp = new Integer(sizeTF.getText());
					tmp += 1;
					sizeTF.setText(tmp.toString());

				}

				if (ae.getSource().equals(changeBT))
				{

					Seminar.getUserGroupByName(
							groupsList.getSelectedValue().toString())
							.getRoles().get(new Integer(roleSelCB.getName()))
							.setName(roleSelCB.getSelectedItem().toString());

					loadGroupRoles();

				}

				if (ae.getSource().equals(freeRoleBT))
				{
					ListIterator<Role> roleIter = Seminar
							.getUserGroupByName(
									groupsList.getSelectedValue().toString())
							.getRoles().listIterator();
					Student tmpst;
					while (roleIter.hasNext())
					{
						if ((tmpst = roleIter.next().getStudent()) != null
								&& tmpst.getLastName().equals(
										ownerDataTF.getName()))
						{
							// roleIter.previous();
							// roleIter.next().removeStudent();
							Seminar.getUserGroupByName(
									groupsList.getSelectedValue().toString())
									.removeStudent(tmpst);
							Seminar.getSystemgroup().addStudent(tmpst);
							loadGroupRoles();
							GUI.statusausgabe("Student wurde der Systemgruppe hinzugefügt!");
							ownerDataTF.setText("");
							break;
						}
					}

				}
			}

		};

	}

	private ActionListener factRoleSelected()
	{

		return new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent ae)
			{

				if (ae.getSource().equals(roleSelCB))
				{

					roleSelCB.getSelectedIndex();
				}
			}

		};
	}

	public void updateEditGroupsPane()
	{

		loadSeminarData();

		loadGroupRoles();
		loadFactoryRoles();

	}
	
	private void enableGroupContent(boolean enabled){
		
		this.curGroupLessMembersBT.setEnabled(enabled);
		this.curGroupMoreMembersBT.setEnabled(enabled);
	}
	
	private void enableRoleContent(boolean enabled){
		
		this.ownerDataTF.setEnabled(enabled);
		this.changeBT.setEnabled(enabled);
		this.freeRoleBT.setEnabled(enabled);
		this.roleSelCB.setEnabled(enabled);
	}

}
